package com.cssl.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cssl.pojo.Dept;
import com.cssl.pojo.Emp;
import com.cssl.pojo.Users;
import com.cssl.service.DeptService;
import com.cssl.service.EmpService;
import com.cssl.service.UsersService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.regex.Pattern;

@RequestMapping("/mongo")
@RestController
public class MongoController {

    //========mongotemplate========
    @Resource
    private MongoTemplate template;
    @Resource
    private EmpService empService;
    @Resource
    private DeptService deptService;

    //===========多对一级联===========
    @GetMapping("/findAllEmp")
    public List<Emp> findAllEmp(){
        IPage page = empService.find(
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<Emp>(1,8),
                new QueryWrapper<Emp>());
        template.insert(page.getRecords(), Emp.class);
        return page.getRecords();
    }

    /*
     * 多对一新增：新增一个员工,emp只有外键值没有部门对象
     */
    @GetMapping("/saveEmp")
    public Emp saveEmp(Emp emp){
        //mysql
        empService.save(emp);
        Dept dept = deptService.getById(emp.getDeptNo());
        //mongodb：要设置关联关系
        emp.setDept(dept);
        return template.save(emp);
    }

    /*
     * 多对一更新：更新某个员工的部门编号
     */
    @GetMapping("/updateEmp1")
    public Emp updateEmp1(Emp emp){
        //mysql
        empService.updateById(emp);
        Dept dept = deptService.getById(emp.getDeptNo());
        //mongodb
        emp.setDept(dept);
        return template.save(emp);
    }

    /*
     * 多对一更新：更新部门必须更新所有员工的部门对象
     */
    @GetMapping("/updateEmp2")
    public Dept updateEmp2(Dept dept){
        //mysql
        deptService.updateById(dept);
        //mongodb
        Query query = new Query();
        query.addCriteria(Criteria.where("deptNo").is(dept.getDeptno()));
        List<Emp> list = template.find(query,Emp.class);
        list.forEach(e->{
            e.setDept(dept);
            template.save(e);  //级联修改
        });
        return dept;
    }

    /*
     * 多对一删除：删除某个部门
     */
    @GetMapping("/removeDept")
    public Long removeDept(int deptno){
        //mysql
        empService.removeByMap(Map.of("dept_no",deptno));
        deptService.removeById(deptno);
        //mongodb
        Query query = new Query(Criteria.where("dept.deptno").is(deptno));
        return template.remove(query,Emp.class).getDeletedCount();
    }

    //===========一对多级联===========
    @GetMapping("/findDept")
    public List<Dept> findDept(){
        List<Dept> list = template.findAll(Dept.class);
        if(list == null || list.size()==0){
            list = deptService.find();
            list.forEach(d->{
                template.save(d);
            });
        }

        return list;
    }

    /**
     * 一对多新增：某个部门新来员工
     */
    @GetMapping("/saveEmp2")
    public Dept saveEmp2(Emp emp){
        //mysql
        empService.save(emp);
        //mongodb
        Dept dept = template.findById(emp.getDeptNo(),Dept.class);
        Set<Emp> emps = dept.getEmps();
        if(emps == null){
            emps = new HashSet<>();
        }
        emps.add(emp);
        return template.save(dept);
    }


    /*
     * 一对多修改：修改某个部门的某个员工信息
     */
    @GetMapping("/updateDept1")
    public Dept updateDept1(Emp emp){
        //mysql
        empService.updateById(emp);
        //mongodb
        Dept dept = template.findById(emp.getDeptNo(),Dept.class);
        Set<Emp> emps = dept.getEmps();
        emps.remove(emp);
        emps.add(emp);
        return template.save(dept);
    }


    /*
     * 一对多删除：删除某个部门的某个员工信息
     */
    @GetMapping("/removeEmp")
    public Dept removeEmp(Emp emp){
        //mysql
        empService.removeById(emp);
        //mongodb
        Dept dept = template.findById(emp.getDeptNo(),Dept.class);
        Set<Emp> emps = dept.getEmps();
        emps.remove(emp);
        return template.save(dept);
    }


    //===========Users==========
    @GetMapping("/save2")
    public Users save2(Users user){
        //service.saveOrUpdate(user);  //mysql
        return template.save(user);
        //return template.save(user,"myuser");
    }

    @GetMapping("/findById/{id}")
    public Users findById(@PathVariable("id") int id){
        //return template.findById(id,Users.class);
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        return template.findOne(query,Users.class);
    }

    @GetMapping("/update")
    public long update(Users user){
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(user.getId()));
        //要修改的字段
        Update update = new Update();
        update.set("username",user.getUsername()).set("password",user.getPassword());
        return template.updateFirst(query,update,Users.class).getModifiedCount();
    }

    @GetMapping("/delete")
    public long delete(String username){
        Query query = new Query();
        query.addCriteria(Criteria.where("username").is(username));

        return template.remove(query,Users.class).getDeletedCount();
    }

    /**
     * 模糊查询+排序分页
     * @return
     */
    @GetMapping("/findByPage")
    public Map<String,Object> findByPage(String username, Integer pageIndex, Integer pageSize){
        Map<String,Object> map = new HashMap<>();
        //模糊查询
        Pattern pattern = Pattern.compile("^.*" + username + ".*$", Pattern.CASE_INSENSITIVE);
        Query query = new Query();
        query.addCriteria(Criteria.where("username").regex(pattern).and("password").is("123"));

        long total = template.count(query, Users.class);
        map.put("total",total);

        query.with(PageRequest.of(
                pageIndex-1,
                pageSize,
                Sort.by(Sort.Direction.DESC,"id")));
        List<Users> list = template.find(query,Users.class);
        map.put("rows",list);
        map.put("pageIndex",pageIndex);
        map.put("pageSize",pageSize);
        map.put("totalPage",total%pageSize==0?total/pageSize:total/pageSize+1);
        return map;
    }


    //========mongorepository=========
    @Autowired
    private UsersService service;

    @GetMapping("/save")
    public Users save(Users user){
        return service.saveUsers(user);
    }

    @GetMapping("/findByUser")
    public Users findByUser(Users user) {
        return service.findByUser(user);
    }

    @GetMapping("/findByUsername/{username}/{pageIndex}/{pageSize}")
    public Page<Users> findByUsernameLike(
            @PathVariable("username") String username,
            @PathVariable("pageIndex") int pageIndex,
            @PathVariable("pageSize") int pageSize) {
        return service.findByUsernameLike(username,pageIndex,pageSize);
    }

}
